type Horse = { name: string };

type OnlyBoolsAndHorses = {
    [key: string]: boolean | Horse;
}

const conforms: OnlyBoolsAndHorses = {
    del: true,
    rodney: false
}

type OptionsFlags<T> = {
    [Property in keyof T]: boolean;
}

type FeatureFlags = {
    darkMode: () => void;
    newUserProfile: () => void;
}

// type FeatureOptions = {
//     darkMode: boolean;
//     newUserProfile: boolean;
// }
type FeatureOptions = OptionsFlags<FeatureFlags>;


// ----------------
// Mapping Modifiers
// ----------------

type CreateMutable<Type> = {
    -readonly [Property in keyof Type]: Type[Property]
}

type LockedAccount = {
    readonly id: string;
    readonly name: string;
}

// type UnlockedAccount = {
//     id: string;
//     name: string;
// }
type UnlockedAccount = CreateMutable<LockedAccount>;

type Concrete<Type> = {
    [Property in keyof Type]-?: Type[Property]
}

type MaybeUser = {
    id: string;
    name?: string;
    age?: number;
}

// type User = {
//     id: string;
//     name: string;
//     age: number;
// }
type User = Concrete<MaybeUser>;

type Getters<Type> = {
    [Property in keyof Type as `get${Capitalize<Property & string>}`]: () => Type[Property]
};

interface Person {
    name: string;
    age: number;
    location: string;
}

// type LazyGetters = {
//     getName: () => string;
//     getAge: () => number;
//     getLocation: () => string;
// }
type LazyGetters = Getters<Person>;

type RemoveKindFiled<Type> = {
    [Property in keyof Type as Exclude<Property, 'kind'>]: Type[Property];
};

interface Circle {
    kind: 'circle';
    radius: number;
}

// type KindlessCircle = {
//     radius: number;
// }
type KindlessCircle = RemoveKindFiled<Circle>;


type EventConfig<Events extends { kind: string }> = {
    [E in Events as E['kind']]: (event: E) => void
};

type SqureEvent = { kind: 'square', x: number, y: number };
type CircleEvent = { kind: 'circle', radius: number };

// type config = {
//     square: (event: SqureEvent) => void;
//     circle: (event: CircleEvent) => void;
// }
type config = EventConfig<SqureEvent | CircleEvent>

type ExtractPII<Type> = {
    [Property in keyof Type]: Type[Property] extends  { pii: true } ? true : false;
};

type DBFields = {
    id: { format: 'incrementing' };
    name: { type: string, pii: true };
};

// type ObjectsNeedingGDPRDeletion = {
//     id: false;
//     name: true;
// }
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;

export {};